package com.study.designpattern.singleton;

import com.sun.org.apache.bcel.internal.classfile.InnerClass;
import com.sun.xml.internal.ws.developer.Serialization;

import java.io.*;
import java.lang.reflect.Constructor;
import java.lang.reflect.InvocationTargetException;

public class InnerClassSingletonTest{
    public static void main(String[] args) throws NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException, IOException, ClassNotFoundException {
//        InnerClassSingleton instance=InnerClassSingleton.getInstance();
//        InnerClassSingleton instance2=InnerClassSingleton.getInstance();
//        System.out.println(instance);
//        System.out.println(instance2);
        /**
         * 多线程访问，也是单例
         * new Thread(()->{
         InnerClassSingleton instance=InnerClassSingleton.getInstance();
         System.out.println(instance);
         }).start();
         new Thread(()->{
         InnerClassSingleton instance2=InnerClassSingleton.getInstance();
         System.out.println(instance2);
         }).start();
         */
//        反射攻击
//        Constructor<InnerClassSingleton> declaredConstructor=InnerClassSingleton.class.getDeclaredConstructor();
//        declaredConstructor.setAccessible(true);
//        InnerClassSingleton instance=declaredConstructor.newInstance();
//        InnerClassSingleton instance2=InnerClassSingleton.getInstance();
//        System.out.println(instance);
//        System.out.println(instance2);
        InnerClassSingleton instance=InnerClassSingleton.getInstance();
//        ObjectOutputStream oos=new ObjectOutputStream(new FileOutputStream("InnerClassSingletonSerialization"));
//        oos.writeObject(instance);
//        oos.close();
        ObjectInputStream ois=new ObjectInputStream(new FileInputStream("InnerClassSingletonSerialization"));
        InnerClassSingleton instance1=(InnerClassSingleton)ois.readObject();
        ois.close();
        System.out.println(instance);
        System.out.println(instance1);




    }
}
class InnerClassSingleton implements Serializable{
    //加上serialVersionUID防止兼容对文件的修改
    static final long serialVersionUID = 42L;
  private static class InnerClassSingletonHolder{
      private static InnerClassSingleton instance=new InnerClassSingleton();
    }
    private InnerClassSingleton(){
      //阻止反射实例化第二个instance
      if (InnerClassSingletonHolder.instance!=null){
          throw new RuntimeException("Muti-instances is not allowed!");
      }
    }

    public static InnerClassSingleton getInstance() {
        return InnerClassSingletonHolder.instance;
    }
    //解决序列化后instance不一致的问题
    Object readResolve() throws ObjectStreamException{
        return InnerClassSingletonHolder.instance;
    }
}